/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ua.lviv.franko.nonequidistant.FEMShapeFunctions1D;

import java.util.ArrayList;

import ua.lviv.franko.FEMShapeFunction1D.IFEM1D;
import ua.lviv.franko.integration.IFunction1D;
import ua.lviv.franko.mlsFunctions.oneDimension.ICalculate;

/**
 * 
 * @author mark_o
 */
public class FEMShapeFunction1D1Pow implements IFunction1D, IFEM1D, ICalculate {
	double	xi;
	double	hLeft;
	double	hRight;

	public FEMShapeFunction1D1Pow(double xi, double hLeft, double hRight) {
		this.xi = xi;
		this.hLeft = hLeft;
		this.hRight = hRight;
	}

	public double calculate(double x) {
		if ((x < xi - hLeft) || (x > xi + hRight)) {
			return 0.0;
		}
		if (x < xi) {
			// return ((x-xi+hLeft)*10000.0) / (hLeft*10000.0);
			return ((x - xi + hLeft)) / (hLeft);
		} else {
			// return ((x-xi-hRight)*10000.0)/(-hRight*10000.0);
			return ((x - xi - hRight)) / (-hRight);
		}
	}

	@Override
	public double[] calculateAll(double x) {
		return new double[] { this.calculate(x), this.calculateDerivaty(x) };
	}

	public double calculateDerivaty(double x) {
		if ((x < xi - hLeft) || (x > xi + hRight)) {
			return 0.0;
		}
		if (xi - x > 0) {
			return 1.0 / hLeft;
		} else {
			return -1.0 / hRight;
		}
	}

	public double[] getBounds() {
		return new double[] { xi - hLeft, (xi + hRight) };
	}

	public double gethLeft() {
		return hLeft;
	}

	public double gethRight() {
		return hRight;
	}

	public double getXi() {
		return xi;
	}


	@Override
	public double getH() {
		throw new UnsupportedOperationException();
	}
	
	public static void main(String[] args) {
		// ArrayList<Double> list = new ArrayList<Double>();
		double a = 0;
		double b = 1;
		int N = 130;
		double h = (b - a) / N;
		// for (int i = 0; i <= N; i++) {
		// list.add(a+h*i);
		// }
		FEMShapeFunction1D1Pow f = new FEMShapeFunction1D1Pow(0.5, 20 * h, 40 * h);
		// for(int j=0;j<=N;j++){
		h = (b - a) / 1000.0;
		System.out.println("f([");
		for (int i = 0; i <= 1000; i++) {
			System.out.println((a + h * i) + "\t\t" + f.calculate(a + h * i));
		}
		System.out.println("])");
		// }

		ArrayList<Double> list = new ArrayList<Double>();
		list.add(0.0);
		list.add(0.025);
		list.add(0.05);
		list.add(0.07500000000000001);
		list.add(0.1);
		list.add(0.125);
		list.add(0.15000000000000002);
		list.add(0.17500000000000002);
		list.add(0.2);
		list.add(0.225);
		list.add(0.25);
		list.add(0.275);
		list.add(0.30000000000000004);
		list.add(0.325);
		list.add(0.35000000000000003);
		list.add(0.375);
		list.add(0.4);
		list.add(0.42500000000000004);
		list.add(0.45);
		list.add(0.47500000000000003);
		list.add(0.5);
		list.add(0.51);
		list.add(0.52);
		list.add(0.53);
		list.add(0.54);
		list.add(0.55);
		list.add(0.56);
		list.add(0.5700000000000001);
		list.add(0.5800000000000001);
		list.add(0.5900000000000001);
		list.add(0.6);
		list.add(0.61);
		list.add(0.62);
		list.add(0.63);
		list.add(0.64);
		list.add(0.65);
		list.add(0.66);
		list.add(0.67);
		list.add(0.68);
		list.add(0.6900000000000001);
		list.add(0.7000000000000001);
		list.add(0.7100000000000001);
		list.add(0.72);
		list.add(0.73);
		list.add(0.74);
		list.add(0.75);
		list.add(0.76);
		list.add(0.77);
		list.add(0.78);
		list.add(0.79);
		list.add(0.8);
		list.add(0.805);
		list.add(0.81);
		list.add(0.8150000000000001);
		list.add(0.8200000000000001);
		list.add(0.8250000000000001);
		list.add(0.8300000000000001);
		list.add(0.8350000000000001);
		list.add(0.8400000000000001);
		list.add(0.8450000000000001);
		list.add(0.8500000000000001);
		list.add(0.855);
		list.add(0.86);
		list.add(0.865);
		list.add(0.87);
		list.add(0.875);
		list.add(0.88);
		list.add(0.885);
		list.add(0.89);
		list.add(0.895);
		list.add(0.9);
		list.add(0.905);
		list.add(0.91);
		list.add(0.915);
		list.add(0.92);
		list.add(0.925);
		list.add(0.93);
		list.add(0.935);
		list.add(0.9400000000000001);
		list.add(0.9450000000000001);
		list.add(0.95);
		list.add(0.9550000000000001);
		list.add(0.96);
		list.add(0.9650000000000001);
		list.add(0.97);
		list.add(0.975);
		list.add(0.98);
		list.add(0.985);
		list.add(0.99);
		list.add(0.995);
		list.add(1.0);

		ArrayList<FEMShapeFunction1D1Pow> FuncList = new ArrayList<FEMShapeFunction1D1Pow>();
		ArrayList<Double> list1 = new ArrayList<Double>();
		for (int i = 0; i < list.size(); i++) {
			list1.add(Math.sin(list.get(i)));
		}
		ArrayList<Double> NodeList = list;
		FuncList.add(new FEMShapeFunction1D1Pow(NodeList.get(0), 0.0, NodeList.get(1) - NodeList.get(0)));
		for (int i = 1; i < NodeList.size() - 1; i++) {
			double h1 = NodeList.get(i) - NodeList.get(i - 1);
			double h2 = NodeList.get(i + 1) - NodeList.get(i);
			FuncList.add(new FEMShapeFunction1D1Pow(NodeList.get(i), h1, h2));
		}
		int n = NodeList.size() - 1;
		FuncList.add(new FEMShapeFunction1D1Pow(NodeList.get(n), NodeList.get(n) - NodeList.get(n - 1), 0.0));

		h = 1.0 / 10000.0;
		double x = 0.0;
		for (int i = 0; i < 10000; i++) {
			double result = 0.0;
			FEMShapeFunction1D1Pow fEMShapeFunction1D1Pow = null;
			for (int j = 0; j < FuncList.size(); j++) {
				fEMShapeFunction1D1Pow = FuncList.get(j);
				result += list1.get(j) * fEMShapeFunction1D1Pow.calculate(x);
			}
			System.out.println(x + "\t\t" + result);
			x += h;
		}
	}


}
